<?php

namespace Biz\module\Behaviors\Activity;

use Biz\model\activity\FullShipping as mFullShipping;
use Biz\model\activity\FullShippingPlan as mFullShippingPlan;
use Biz\model\activity\FullShippingGoods as mFullShippingGoods;
use Biz\model\activity\ActivityOperateLog as mActivityOperateLog;
use Biz\service\Goods as sGoods;
use Biz\pockets\serviceTrait\_Async;
use Doraemon\tools\Log as tLogs;
use Biz\pockets\constInterface\ActivityInfo;

final class FullShipping
{
    use _Async;

    /**
     * 添加满包邮活动
     * @param $shopId
     * @param $fields
     * @throws \Exception
     */
    public static function add($shopId, $fields)
    {
        $fields = self::checkData($shopId, $fields);

        $result = mFullShipping::action(function () use ($shopId, $fields) {
            $shippingId = mFullShipping::addData($shopId, $fields);
            if ($shippingId) {
                $result = true;
                if ($fields['goods_ids']) {
                    $result = mFullShippingGoods::addData($shopId, $shippingId, $fields['start_time'], $fields['end_time'], $fields['goods_ids']);
                }
                if ($result) {
                    $result = mFullShippingPlan::addData($shopId, $shippingId, $fields['shipping_plan']);
                }
            } else {
                return false;
            }
            if ($result) {
                return $shippingId;
            } else {
                return false;
            }
        });
        if ($result) {
            //添加满包邮活动日志
            $operateData = [
                'all_goods' => $fields['all_goods'],
                'goods_ids' => $fields['goods_ids'],
                'shipping_plan' => $fields['shipping_plan'],
            ];
            $logData = [
                'type_id' => ActivityInfo::ACTIVITY_TYPE_FULL_SHIPPING,
                'activity_id' => $result,
                'shop_id' => $shopId,
                'title' => $fields['title'],
                'type' => $fields['type'],
                'start_time' => $fields['start_time'],
                'end_time' => $fields['end_time'],
                'status' => mFullShippingPlan::STATUS_ACTIVE,
                'operate_data' => json_encode($operateData, JSON_UNESCAPED_UNICODE),
                'operate_type' => 1,
            ];
            mActivityOperateLog::addLogData($logData);
        } else {
            throw new \Exception('创建满包邮失败');
        }
    }

    /**
     * 编辑满包邮
     * @param $shopId
     * @param $shippingId 满包邮活动id
     * @param $fields
     * @throws \Exception
     */
    public static function EditActivitys($shopId, $shippingId, $fields)
    {
        try {
            $fields = self::checkData($shopId, $fields, true, $shippingId);
            $goodsIds = $fields['goods_ids'];
            $exitGoodsIds = mFullShippingGoods::getList(['shipping_id' => $shippingId], ['goods_id']);
            $exitGoodsIds = $exitGoodsIds ? array_column($exitGoodsIds, 'goods_id') : [];
            $result = mFullShipping::action(function () use ($shopId, $shippingId, $fields, $goodsIds, $exitGoodsIds) {
                $result = mFullShipping::edit($shippingId, $shopId, [
                    'title' => $fields['title'],
                    'start_time' => $fields['start_time'],
                    'end_time' => $fields['end_time'],
                    'all_goods' => $fields['all_goods'],
                ]);
                if ($result) {
                    if (!$goodsIds) {
                        $result = mFullShippingGoods::updateData(['status' => mFullShippingGoods::STATUS_DELETE], ['shipping_id' => $shippingId]);
                    } else {
                        if ($exitGoodsIds) {
                            $result = mFullShippingGoods::updateData(
                                [
                                    'status' => mFullShippingGoods::STATUS_ACTIVE,
                                    'start_time' => $fields['start_time'],
                                    'end_time' => $fields['end_time']
                                ],
                                [
                                    'shipping_id' => $shippingId, 'goods_id' => $goodsIds
                                ]
                            );
                        }
                        $noExitGoodsIds = array_diff($goodsIds, $exitGoodsIds);
                        if ($noExitGoodsIds) {
                            $result = mFullShippingGoods::addData($shopId, $shippingId, $fields['start_time'], $fields['end_time'], $noExitGoodsIds);
                            if (!$result) {
                                return false;
                            }
                            $goodsIds = array_merge($goodsIds, $noExitGoodsIds);
                        }
                        if ($result) {
                            $result = mFullShippingGoods::updateData(['status' => mFullShippingGoods::STATUS_DELETE], ['shipping_id' => $shippingId, 'goods_id[!]' => $goodsIds]);
                        } else {
                            return false;
                        }
                    }
                    if ($result) {
                        $PlanData = [];
                        $currentIds = [];
                        $result = true;
                        foreach ($fields['shipping_plan'] as $plans) {
                            if (isset($plans['id'])) {
                                if ($result) {
                                    $result = mFullShippingPlan::editPlan($plans['id'], [
                                        'total_unit' => $plans['total_unit'],
                                        'province_ids' => $plans['province_ids'],
                                    ]);
                                    $currentIds[] = $plans['id'];
                                } else {
                                    return false;
                                }
                            } else {
                                $PlanData[] = [
                                    'total_unit' => $plans['total_unit'],
                                    'province_ids' => $plans['province_ids'],
                                ];
                            }
                        }

                        if ($currentIds) {
                            if ($result) {
                                $result = mFullShippingPlan::updateData(['status' => mFullShippingPlan::STATUS_DELETE], [
                                    'shop_id' => $shopId,
                                    'shipping_id' => $shippingId,
                                    'id[!]' => $currentIds
                                ]);
                            }
                        }
                        if ($result) {
                            if ($PlanData) {
                                $result = mFullShippingPlan::addData($shopId, $shippingId, $PlanData);
                            }
                        } else {
                            return false;
                        }
                    } else {
                        return false;
                    }
                } else {
                    return false;
                }
                return $result;
            });
            if ($result) {
                //添加满包邮活动日志
                $operateData = [
                    'all_goods' => $fields['all_goods'],
                    'goods_ids' => $fields['goods_ids'],
                    'shipping_plan' => $fields['shipping_plan'],
                ];
                $logData = [
                    'type_id' => ActivityInfo::ACTIVITY_TYPE_FULL_SHIPPING,
                    'activity_id' => $shippingId,
                    'shop_id' => $shopId,
                    'title' => $fields['title'],
                    'type' => $fields['type'],
                    'start_time' => $fields['start_time'],
                    'end_time' => $fields['end_time'],
                    'status' => mFullShippingPlan::STATUS_ACTIVE,
                    'operate_data' => json_encode($operateData, JSON_UNESCAPED_UNICODE),
                    'operate_type' => 2,
                ];
                mActivityOperateLog::addLogData($logData);
            } else {
                throw new \Exception('编辑满包邮失败');
            }
        } catch (\Exception $e) {
            tLogs::warning("编辑满包邮失败 ", ['error_msg' => $e->getMessage(), 'error_file' => $e->getFile(), 'erro_line' => $e->getLine(), 'error_code' => $e->getCode()]);
            throw new \Exception($e->getMessage());
        }
    }

    /**
     * 检查活动的数据是否正常
     * @param $shopId
     * @param $fields
     * @param bool $isUpdate
     * @param int $shippingId
     * @return mixed
     * @throws \Exception
     */
    private static function checkData($shopId, $fields, $isUpdate = false, $shippingId = 0)
    {
        $fields['start_time'] = date("Y-m-d H:i:s", strtotime($fields['start_time']));
        $fields['end_time'] = date("Y-m-d H:i:s", strtotime($fields['end_time']));
        $shippingPlans = $fields['shipping_plan'] = json_decode($fields['shipping_address'], true);
        if ($fields['end_time'] < date("Y-m-d H:i:s") || $fields['start_time'] >= $fields['end_time']) {
            throw new \Exception('活动时间有误');
        }
        if (!$fields['all_goods'] && !$fields['goods_ids']) {
            throw new \Exception('请选择商品');
        }
        $fields['goods_ids'] = $fields['goods_ids'] ? json_decode($fields['goods_ids'], true) : [];
        $isExist = mFullShipping::TimeRangeIsCover($shopId, $fields['start_time'], $fields['end_time'], $isUpdate, $shippingId);
        if ($isExist) {
            throw new \Exception('该时段满包邮已经存在');
        }
        $provinceIds = [];
        foreach ($shippingPlans as $key => $shippingPlan) {
            if (array_intersect($provinceIds, $shippingPlan['province_ids'])) {
                throw new \Exception('相同时间内存在相同满包邮省份');
            }
            if (!$shippingPlan['province_ids'] || !$shippingPlan['total_unit']) {
                throw new \Exception('满包邮金额(或件数)和收货地都需要填写');
            }
            $provinceIds = array_merge($provinceIds, $shippingPlan['province_ids']);

            $shippingPlans[$key]['total_unit'] = (int)$shippingPlan['total_unit'];
            $shippingPlans[$key]['province_ids'] = implode(',', $shippingPlan['province_ids']);
        }

        $fields['shipping_plan'] = $shippingPlans;
        return $fields;
    }

    /**
     * @param $shopId
     * @return array
     * @throws \Exception
     */
    public static function ActivityList($shopId)
    {
        $fullShippings = mFullShipping::getActivePlanList([$shopId], mFullShipping::STATUS_ACTIVE, true);
        if (isset($fullShippings[$shopId])) {
            $fullShippings = $fullShippings[$shopId];
        }
        $goodsIdsArr = array_column($fullShippings, 'goods_ids');
        $goodsIds = [];
        foreach ($goodsIdsArr as $row) {
            if ($row) {
                $goodsIds = array_merge($goodsIds, $row);
            }
        }
        $goodsIds = array_unique($goodsIds);
        $goodsList = sGoods::goods($goodsIds);
        $formatRst = [];
        foreach ($fullShippings as $key => $fullShipping) {
            $formatRst[$fullShipping['shipping_id']]['id'] = $fullShipping['shipping_id'];
            $formatRst[$fullShipping['shipping_id']]['key'] = (int)$key;
            $formatRst[$fullShipping['shipping_id']]['type_id'] = ActivityInfo::ACTIVITY_TYPE_FULL_SHIPPING;
            $formatRst[$fullShipping['shipping_id']]['shipping_title'] = $fullShipping['title'];
            $formatRst[$fullShipping['shipping_id']]['type_des'] = ActivityInfo::ACTIVITY_TYPES_MAPS[ActivityInfo::ACTIVITY_TYPE_FULL_SHIPPING];
            $formatRst[$fullShipping['shipping_id']]['time_range'] = $fullShipping['start_time'] . " - " . $fullShipping['end_time'];
            $formatRst[$fullShipping['shipping_id']]['start_time'] = $fullShipping['start_time'];
            $formatRst[$fullShipping['shipping_id']]['end_time'] = $fullShipping['end_time'];
            $formatRst[$fullShipping['shipping_id']]['shipping_type'] = $fullShipping['type'];
            $formatRst[$fullShipping['shipping_id']]['shipping_type_desc'] = mFullShipping::$typeDesc[$fullShipping['type']];
            $formatRst[$fullShipping['shipping_id']]['all_goods'] = $fullShipping['all_goods'];
            $formatRst[$fullShipping['shipping_id']]['goods_ids'] = $fullShipping['goods_ids'];
            $formatRst[$fullShipping['shipping_id']]['status'] = $fullShipping['status'];
            foreach ($fullShipping['goods_ids'] as $goodsId) {
                $goodsInfo = $goodsList[$goodsId];
                $formatRst[$fullShipping['shipping_id']]['goods_list'][] = [
                    'goods_id' => $goodsInfo['id'],
                    'goods_title' => $goodsInfo['title'],
                    'spec_img_thumb_url' => $goodsInfo['cover_img']
                ];
            }
            $formatRst[$fullShipping['shipping_id']]['shipping_address'][] = [
                'id' => $fullShipping['id'],
                'total_unit' => $fullShipping['total_unit'],
                'province_ids' => explode(",", $fullShipping['province_ids']),
                'province_desc' => $fullShipping['province_desc'],
            ];

        }

        return array_values($formatRst);
    }

    /**
     * @param $shopId 店铺id
     * @param $shippingId 满包邮活动id
     * @return bool
     * @throws \Exception
     */
    public static function changeStatus($shopId, $shippingId)
    {
        $result = mFullShipping::action(function () use ($shippingId, $shopId) {
            $result = mFullShipping::edit($shippingId, $shopId, [
                'status' => mFullShipping::STATUS_INVALID
            ]);
            if ($result) {
                $result = mFullShippingPlan::updateData([
                    'status' => mFullShippingPlan::STATUS_INVALID
                ], ['shipping_id' => $shippingId]);
            }
            if ($result) {
                $result = mFullShippingGoods::updateData(['status' => mFullShippingGoods::STATUS_INVALID], ['shipping_id' => $shippingId]);
            }
            return $result;
        });
        if ($result) {
            //添加满包邮活动日志
            $logData = [
                'type_id' => ActivityInfo::ACTIVITY_TYPE_FULL_SHIPPING,
                'activity_id' => $shippingId,
                'shop_id' => $shopId,
                'status' => mFullShippingPlan::STATUS_INVALID,
                'operate_type' => 3,
            ];
            mActivityOperateLog::addLogData($logData);
        } else {
            throw new \Exception('设置活动失效失败');
        }
        return $result;
    }
}